package com.laoyang.dtp;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.ByteArrayResource;

import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


/**
 * @author:Kevin
 * @create: 2023-10-24 19:56
 * @Description: nacos自带监听器
 */

public class NacosLinsenter implements Listener, InitializingBean {

    @NacosInjected
    private ConfigService configService;

    //nacos的dataId的名称
    private static final String DATA_ID = "dtp.yaml";

    private static final String GROUP = "DEFAULT_GROUP";


    //创建一个线程池供下面的调用
    @Override
    public Executor getExecutor() {
        return Executors.newFixedThreadPool(1);
    }

    //每次当前的dataId只要改变，就会调用这个方法
    //但是调用这个方法的线程需要上面的方法创建一个线程池
    @Override
    public void receiveConfigInfo(String s) {
        //首先需要将字符串yml格式转化为map的格式(单个线程池)
        YamlPropertiesFactoryBean factoryBean = new YamlPropertiesFactoryBean();
        factoryBean.setResources(new ByteArrayResource(s.getBytes()));
        //使用springboot内置工具类转换为Properties类似于map的格式
        Properties properties = factoryBean.getObject();

        //首先需要将字符串yml格式转化为List的格式(多个线程池)
        DtpProperties dtpProperties = new DtpProperties();
        MapConfigurationPropertySource sources = new MapConfigurationPropertySource(properties);
        Binder binder = new Binder(sources);
        ResolvableType type = ResolvableType.forClass(DtpProperties.class);
        Bindable<?> target = Bindable.of(type).withExistingValue(dtpProperties);
        binder.bind("dtp",target);

        //获取到更改配置的内容
        List<DtpProperties.DtpExecutorProperties> executors = dtpProperties.getDtpExecutors();

        //将改过的数据注入bean中
        for (DtpProperties.DtpExecutorProperties executor : executors) {
            //获取bean对象
            DtpExecutor dtpExecutor = DtpUtil.get(executor.getName());
            //然后修改数据
            dtpExecutor.setCorePoolSize(executor.getCorePoolSize());
            dtpExecutor.setMaximumPoolSize(executor.getMaximumPoolSize());

        }

        //获取更新后的数据
//        String corePoolSize = properties.getProperty(CORE_POOL_SIZE);
//        String maximumPoolSize = properties.getProperty(MAXIMUM_POOL_SIZE);
//        //直接更新数据
//        executor.setCorePoolSize(Integer.parseInt(corePoolSize));
//        executor.setMaximumPoolSize(Integer.parseInt(maximumPoolSize));

    }

    @Override
    public void afterPropertiesSet() throws Exception {
        //将这个NacosLinsenter与当前的dataId一一绑定
        configService.addListener(DATA_ID,GROUP,this);
    }
}
